package controller;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import XMLReader.Driver;

import entity.Model;

import interfaceEntity.IModelController;


public class ModelController  implements IModelController
{
	private static ModelController _instance;
	private List<String> rawData;
	private Map<String, Model> models;
	private Driver driver;
	private String[] firmwareVer;//temporary
	//String dateVersion;
	private Calendar myDate;
	private ModelController()
	{
		rawData= new ArrayList<String>();
		models= new HashMap<String, Model>();
		myDate=null;
	}

	public synchronized static ModelController getModelController()
	{
		if(_instance == null)
		{
			_instance = new ModelController();
			
		}
		return _instance;
	}
	
	//set database version
	private boolean databaseVersion()
	{
		String stringDate = firmwareVer[0];
		myDate = new GregorianCalendar();
		try
		{
			Date theDate = new SimpleDateFormat("dd.MM.yyyy", Locale.ROOT).parse(stringDate);
			myDate.setTime(theDate);
			getDateFromModels();
			return true;

		}
		catch (Exception e) 
		{
			System.err.println("error parse");
			return false;
		}


	}
	
	//remove date  value from models 
	private void getDateFromModels()
	{
		String []newModels=new String[firmwareVer.length-1];
		for(int i=1; i<firmwareVer.length;i++)
		{
			newModels[i-1]=firmwareVer[i];
		}
		firmwareVer=newModels;
		                              
	}
	
	@Override
	public boolean xmlData(List<String> rawData)
	{
		this.rawData=rawData;
		driver = new Driver();
		if(driver.setFirmwareValues(rawData))
		{
			firmwareVer=driver.firmwareValues();
			//set database date value, remove date from models
			if(!databaseVersion())
				return false;
			for(String selected: firmwareVer)
			{
				//check if build data successfully, add data to HashMap Table
				if(driver.setErrors(rawData, selected))
					models.put(selected, new Model().model(selected, driver.errorsDescription()));
				else//build data not successfully, return false
					return false;
					
			}
			return true;
		}
		else
			return false;
		
	}

	@Override
	//return error description by error number
	public String errorDescription(String name, int errorNum) 
	{
		if(models.containsKey(name))
		{
			 String errDesc=models.get(name).getDescriptionByErrorID(errorNum);
			 return(errDesc==null ? null : errDesc);
		}
		return null;
	}

	@Override
	//return Firmware versions values
	public String[] modelValues() 
	{
		/*Set<String> set = models.keySet();
		String [] values= new String[set.size()] ;
		return set.toArray(values)*/;
		return firmwareVer;
	}

	@Override
	//check if current version of database is last
	public boolean isLastVersion(Calendar databaseVersion) 
	{
		if(myDate==null)
			return false;
		if(myDate!=null && myDate.before(databaseVersion))
			return false;
		return true;
		
	}

	@Override
	//convert binary to integer
	public int selectednumber(boolean[] selectedButtons) 
	{
		boolean []revSelectedButtons = new boolean [selectedButtons.length];
		for(int i=selectedButtons.length-1; i>-1;)
		{
			for(int a=0; a<revSelectedButtons.length; a++)
			{
				revSelectedButtons[a]=selectedButtons[i];
				--i;
			}
		}
		                                            
		int intButtons=0;
		for(int i=0; i<revSelectedButtons.length; i++)
		{
			
			if(revSelectedButtons[i])
				intButtons+=(int)Math.pow(2, i);
		}
		return intButtons;
	}
	
	
}
